package data.platform.common.merge;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.time.LocalDateTime;
import java.util.concurrent.atomic.AtomicBoolean;

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = CommonAggregateItem.class, name = "common"),
        @JsonSubTypes.Type(value = LoadPercentAggregateItem.class, name = "loadPercent"),
        @JsonSubTypes.Type(value = IfCrowdTimeAggregateItem.class, name = "ifCrowdTime"),
        @JsonSubTypes.Type(value = FaultAggregateItem.class, name = "fault")
})
@Getter
@Setter
@NoArgsConstructor
public abstract class AggregateItem {

    protected MergePeriod mergePeriod;

    protected MergeTimeWindow mergeTimeWindow;

    @JsonIgnore
    protected AtomicBoolean dirty = new AtomicBoolean(true);

    @JsonIgnore
    public static final String KEY_PRE_NAME = "merge";

    @JsonIgnore
    public static final String KEY_SEPARATOR = "|";

    public AggregateItem(MergePeriod mergePeriod, MergeTimeWindow mergeTimeWindow) {
        this.mergePeriod = mergePeriod;
        this.mergeTimeWindow = mergeTimeWindow;
    }

    // merge -> mergeTimeWindow -> arithmeticType -> metric -> tagId
    public static String getKey(MergeTimeWindow mergeTimeWindow, ArithmeticType arithmeticType, String metric, Integer tagId) {
        return String.join(KEY_SEPARATOR, getPrefixKey(),
                "" + mergeTimeWindow.getStartTime(),
                "" + mergeTimeWindow.getEndTime(),
                arithmeticType.name(),
                metric,
                tagId.toString());
    }

    public static String getPrefixKey() {
        return String.join(KEY_SEPARATOR, KEY_PRE_NAME);
    }

    public abstract void compute(Double value, LocalDateTime eventTime);
}
